/* 
 * Enterprise Library Extensions - DI + ORM.
 * Copyright (C) 2006
 *
 * GNU General Public License
 *
 * This program is free software; you can redistribute 
 * it and/or modify it under the terms of the GNU General Public License 
 * as published by the Free Software Foundation; either version 2 of the 
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; without even the implied warranty of 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
 * See the GNU General Public License for more details.
 */
using System;

namespace ELE.EnterpriseLibrary.Naming
{
  /// <summary>
  /// This class represents a name-to-object binding found in a context. 
  /// A context consists of name-to-object bindings. The Binding class represents such a binding. 
  /// It consists of a name and an object. The Context.listBindings() method returns an enumeration 
  /// of Binding. 
  /// Use subclassing for naming systems that generate contents of a binding dynamically. 
  /// 
  /// A Binding instance is not synchronized against concurrent access by multiple threads. 
  /// Threads that need to access a Binding concurrently should synchronize amongst themselves 
  /// and provide the necessary locking. 
  /// </summary>
  [Serializable]
	public class Binding : NameClassPair
	{
    private object mObject;
    /// <summary>
    /// Constructs an instance of a Binding given its name and object.
    /// </summary>
    /// <param name="name"></param>
    /// <param name="obj"></param>
    public Binding(string name, object obj):this(name,obj,false)
    {
    }
    /// <summary>
    /// Constructs an instance of a Binding given its name, object, and whether the name is relative.
    /// </summary>
    /// <param name="name"></param>
    /// <param name="obj"></param>
    /// <param name="isRelative"></param>
   
    public Binding(string name, object obj, bool isRelative):this(name,null,obj,isRelative) 
    {
    }
    /// <summary>
    /// Constructs an instance of a Binding given its name, class name, and object.
    /// </summary>
    /// <param name="name"></param>
    /// <param name="className"></param>
    /// <param name="obj"></param>   
    public Binding(string name, string className, object obj):this(name,className,obj,false) 
    {
    }
    /// <summary>
    /// Constructs an instance of a Binding given its name, class name, and object.
    /// </summary>
    /// <param name="name"></param>
    /// <param name="className"></param>
    /// <param name="assemblyName"></param>
    /// <param name="obj"></param>
    public Binding(string name, string className, string assemblyName, object obj):this(name,className,assemblyName,obj,false) 
    {
    }
    /// <summary>
    /// Constructs an instance of a Binding given its name, class name, object, and whether the name is relative. 
    /// </summary>
    /// <param name="name"></param>
    /// <param name="className"></param>
    /// <param name="obj"></param>
    /// <param name="isRelative"></param>
    public Binding(string name, string className, object obj, bool isRelative):this(name,className,null,obj,isRelative) 
    {
    }
    /// <summary>
    /// Constructs an instance of a Binding given its name, class name, object, and whether the name is relative. 
    /// </summary>
    /// <param name="name"></param>
    /// <param name="className"></param>
    /// <param name="assemblyName"></param>
    /// <param name="obj"></param>
    /// <param name="isRelative"></param>
    public Binding(string name, string className, string assemblyName, object obj, bool isRelative):base(name,className,assemblyName,isRelative) 
    {
      mObject = obj;
    }
    /// <summary>
    /// Retrieves the class name of the object bound to the name of this binding.
    /// If the class name has been set explicitly, return it. Otherwise, if this binding 
    /// contains a non-null object, that object's class name is used. Otherwise, null is returned.
    /// </summary>
    public override string ClassName
    {
      get
      {
        if(mClassName == null && mObject != null)
        {
          return mObject.GetType().FullName;
        }
        return mClassName;
      }
    }
    /// <summary>
    /// Retrieves the class name of the object bound to the name of this binding.
    /// </summary>
    public override string AssemblyName
    {
      get
      {
        if(mAssemblyName == null && mObject != null)
        {
          return mObject.GetType().Assembly.FullName;
        }
        return mAssemblyName;
      }
    }
    /// <summary>
    /// Class name + , + assembly name
    /// </summary>
    public override string ClassAssemblyName
    {
      get
      {
        return ClassName + "," + AssemblyName;
      }
    }
    /// <summary>
    /// Retrieves and sets the object bound to the name of this binding.
    /// </summary>
    public object Object
    {
      get
      {
        return mObject;
      }
      set
      {
        mObject = value;
      }
    }
    /// <summary>
    /// Generates the string representation of this binding. 
    /// </summary>
    /// <returns></returns>
    public override string ToString() 
    {
      return mName + ":" + mClassName + "," + mAssemblyName + ":" + mObject.ToString();
    }
                                                        

	}
}
